#include <REG51.H>
#include <Clock.h>
#include <Stopwatch.h>
#include <Mode.h>
#include <Buzzer.h>

#define TIME0_TH0 0x3C // 定时器初值，每50ms中断一次
#define TIME0_TL0 0xB0 // 65536-50000 = 0x3CB0

Clock_TypeDef Clock_buff; // 记录日期时间的静态全局变量
bit Clock_Tick = 0;              // 时钟滴答

/**
 * @brief  时钟功能初始化
 * @param  None
 * @retval None
 */
void Clock_init(void)
{
    // 初始化时间与日期
    Clock_buff.year = 0;
    Clock_buff.month = 1;
    Clock_buff.day = 1;
    Clock_buff.hour = 0;
    Clock_buff.minute = 0;
    Clock_buff.second = 0;
    Clock_buff.millisecond = 0;

    // 定时器0初始化
    TMOD &= 0xF0;
    TMOD |= 0x01; // 方式1，定时器模式
    TH0 = TIME0_TH0;
    TL0 = TIME0_TL0;
    ET0 = 1;
    EA = 1;
    TR0 = 1;
}

/**
 * @brief  判断当前年份是否为闰年，判定条件为：(满足其一即可)
 *         (1) 能被4整除且不能被100整除（如2004年是闰年，而1900年不是闰年）
 *         (2) 能被400整除（如2000年是闰年）
 * @param  None
 * @retval 是（1），否（0）
 */
bit Is_leap_year(void)
{
    int leap_year = Clock_buff.year + 2000;
    if (leap_year % 4 == 0 && leap_year % 100 != 0)
    {
        return 1;
    }
    if (leap_year % 400 == 0)
    {
        return 1;
    }
    return 0;
}

/**
 * @brief  该函数用于更新时钟数据，功能为当有时钟数据发生改变时，检查是否需要进位
 * @param  None
 * @retval None
 */
static void Clock_updata_dateData(void)
{
    if (Clock_buff.millisecond == 10 || Clock_buff.millisecond == 20)
    {
        Clock_Tick = ~Clock_Tick;
    }

    // 毫秒进位
    // 定时器每50ms中断一次，中断时 Clock_buff.millisecond + 1，所以 Clock_buff.millisecond = 20 时，为1000ms
    if (Clock_buff.millisecond < 20)
        return;
    Clock_buff.millisecond = 0;
    Clock_buff.second++;

    // 秒进位
    if (Clock_buff.second < 60)
        return;
    Clock_buff.second = 0;
    Clock_buff.minute++;
    if (System_Mode == Mode_hour_report)
    {
        Buzzer_reset();
        System_Mode = Mode_Clock;
    }

    // 分钟进位
    if (Clock_buff.minute < 60)
        return;
    Clock_buff.minute = 0;
    Clock_buff.hour++;
    System_Mode = Mode_hour_report;

    // 小时进位
    if (Clock_buff.hour < 24)
        return;
    Clock_buff.hour = 0;
    Clock_buff.day++;

    // 天数进位
    if (Clock_buff.day < 28)
    {
        return;
    }
    if (Clock_buff.day == 32)
    {
        Clock_buff.day = 1;
        Clock_buff.month++;
    }
    else if (Clock_buff.day == 31 && (Clock_buff.month == 4 || Clock_buff.month == 6 || Clock_buff.month == 9 || Clock_buff.month == 11))
    {
        Clock_buff.day = 1;
        Clock_buff.month++;
    }
    else if (Clock_buff.day == 30 && Clock_buff.month == 2 && (Is_leap_year() == 1))
    {
        Clock_buff.day = 1;
        Clock_buff.month++;
    }
    else if (Clock_buff.day == 29 && Clock_buff.month == 2 && (Is_leap_year() == 0))
    {
        Clock_buff.day = 1;
        Clock_buff.month++;
    }

    // 月份进位
    if (Clock_buff.month <= 12)
        return;
    Clock_buff.month = 1;
    Clock_buff.year++;
    // 将时钟年份限制在 2000 - 2099 年
    if (Clock_buff.year >= 100)
    {
        Clock_buff.year = 0;
    }
}

/**
 * @brief  定时器0中断服务函数，
 *         定时器0用于 时钟 和 秒表 的精确计时。
 * @param  None
 * @retval None
 */
void time0_int(void) interrupt 1
{
    TL0 = TIME0_TL0;
    TH0 = TIME0_TH0;

    if (Stopwatch_buff.status == Stopwatch_status_start)
    {
        Stopwatch_buff.millisecond += 5;
    }

    Clock_buff.millisecond++;
    Clock_updata_dateData();
    Stopwatch_updata_Data();
}
